package net.kem.android.positioner;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.util.SparseArray;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;
import net.kem.android.positioner.custom.MacroMessageButton;
import net.kem.android.positioner.custom.ServerMessageElement;
import net.kem.android.positioner.custom.ServerMessageSwitch;
import net.kem.android.positioner.custom.ServerMessageSwitchButton;
import net.kem.android.positioner.custom.ServerMessageSwitchSlider;

import java.util.ArrayList;

/**
 * This example is mostly taken from
 * http://www.codeproject.com/Articles/112044/positioner-App-to-Find-Current-Nearest-Location-us
 *
 * @author Evgeny.Kurtser
 *
 */
public class ServerMessagesActivity extends Activity {
	private static final int OBJECT_TYPE_LIGTH =	1;
	private static final int OBJECT_TYPE_HEAT =		6;//3
	private static final int OBJECT_TYPE_AC =		5;
	private static final int OBJECT_TYPE_SECURITY =	7;
	private static final int OBJECT_TYPE_MACROS =	10;

	private static final int CATEGORY_BUTTON =	1;
	private static final int CATEGORY_SLIDER =	2;
	private static final int CATEGORY_IMAGE_TEXT =	3;
	private static final int CATEGORY_DISABLED_BUTTON =	100;

	private PositionerService.LocalBinder binder;
	private SparseArray<ServerMessageTab> messageTabs;

	private class ServerMessageTab {
		private Button button;
		private LinearLayout layout;
		private int imgOff, imgOn;
		ServerMessageTab(Button button, LinearLayout layout, int imgOff, int imgOn) {
			this.button = button;
			this.layout = layout;
			this.imgOff = imgOff;
			this.imgOn = imgOn;
		}
	}

	// Our handler for received Intents. This will be called whenever an Intent with an action named "toastEvent" is broadcasted.
	private BroadcastReceiver toastMessageReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			// Get extra data included in the Intent
			String to = intent.getStringExtra("to");
			if (to != null && (to.length()==0 || ServerMessagesActivity.class.getName().equals(to))) {
				String message = intent.getStringExtra("message");
				if (message != null) {
					Utils.toast(getApplicationContext(), message, Toast.LENGTH_SHORT);
				}
			}
		}
	};

	// Our handler for received Intents. This will be called whenever an Intent
	// with an action named "serverMessageEvent" is broadcasted.
	private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			// Get extra data included in the Intent
			Bundle bundle;
			bundle = intent.getBundleExtra("serverMessage");
			if(bundle != null) {
				ArrayList<MessageObject> messageObjects = bundle.getParcelableArrayList("ServerMessageObjects");
				if(messageObjects != null && messageObjects.size() > 0) {
					// Clear all tabs.
					messageTabs.get(OBJECT_TYPE_AC).layout.removeAllViews();
					messageTabs.get(OBJECT_TYPE_HEAT).layout.removeAllViews();
					messageTabs.get(OBJECT_TYPE_LIGTH).layout.removeAllViews();
					messageTabs.get(OBJECT_TYPE_SECURITY).layout.removeAllViews();
					// Fill appropriate tab(s).
					for(MessageObject messageObject: messageObjects) {
						int msgType = messageObject.getType();
						//LinearLayout ll = (LinearLayout)findViewById(R.id.smLight);
						ServerMessageTab smt = messageTabs.get(msgType);
						if(smt != null) {
							LinearLayout ll = messageTabs.get(msgType).layout;
							ServerMessageElement sme = null;
							switch(messageObject.getCategory()) {
							case CATEGORY_BUTTON:
								sme = new ServerMessageSwitchButton(binder, ServerMessagesActivity.this, smt.imgOff, smt.imgOn, messageObject, true);
								break;
							case CATEGORY_SLIDER:
								sme = new ServerMessageSwitchSlider(binder, ServerMessagesActivity.this, ll, smt.imgOff, smt.imgOn, messageObject);
								break;
							case CATEGORY_IMAGE_TEXT:
								sme = new ServerMessageSwitch(binder, ServerMessagesActivity.this, smt.imgOff, smt.imgOn, messageObject);
								break;
							case CATEGORY_DISABLED_BUTTON:
								sme = new ServerMessageSwitchButton(binder, ServerMessagesActivity.this, smt.imgOff, smt.imgOn, messageObject, false);
								break;
							}
//							TextView tv = new TextView(ServerMessagesActivity.this);
//							tv.setSingleLine();
//							tv.setText(messageObject.toString());
							if(sme != null) {
								ll.addView(sme);
							}
							Log.d("ServerObjects", messageObject.toString());
						} else {
							Log.w("ServerObjects. No layout defined for ", messageObject.toString());
						}
					}
				}
			} else {
				bundle = intent.getBundleExtra("macros");
				if (bundle != null) {
					ArrayList<Macro> macros = bundle.getParcelableArrayList("Macros");
					if(macros != null && macros.size() > 0) {
						// Clear Macros tab.
						messageTabs.get(OBJECT_TYPE_MACROS).layout.removeAllViews();
						// Fill macro tab.
						for(Macro macro: macros) {
							ServerMessageTab smt = messageTabs.get(OBJECT_TYPE_MACROS);
							if(smt != null) {
								LinearLayout ll = smt.layout;
								ServerMessageElement sme = new MacroMessageButton(binder, ServerMessagesActivity.this, smt.imgOn, macro);
								ll.addView(sme);
								Log.d("Macro", macro.toString());
							} else {
								Log.w("Macro. No layout defined for ", macro.toString());
							}
						}
					}
				}
			}
		}
	};
	
	private void hideAllTabs() {
		// Hide all tabs...
		messageTabs.get(OBJECT_TYPE_AC).layout.setVisibility(View.GONE);
		messageTabs.get(OBJECT_TYPE_HEAT).layout.setVisibility(View.GONE);
		messageTabs.get(OBJECT_TYPE_LIGTH).layout.setVisibility(View.GONE);
		messageTabs.get(OBJECT_TYPE_SECURITY).layout.setVisibility(View.GONE);		
		messageTabs.get(OBJECT_TYPE_MACROS).layout.setVisibility(View.GONE);		
	}

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.server_messages);

//		Button buGetServerMessages = (Button)findViewById(R.id.buttonGetServerMessages);
//		buGetServerMessages.setOnClickListener(new OnClickListener() {
//			public void onClick(View view) {
//				binder.sendGetAllObjects(1);
//			}
//		});

//        Button buGetServerMessagesTest = (Button)findViewById(R.id.buttonGetServerMessagesDummy);
//        buGetServerMessagesTest.setOnClickListener(new OnClickListener() {
//        	public void onClick(View view) {
//        		binder.sendGetAllObjects(-1);
//        	}
//        });

//        Button buSetServerMessagesTest = (Button)findViewById(R.id.buttonSetServerMessagesDummy);
//        buSetServerMessagesTest.setOnClickListener(new OnClickListener() {
//        	public void onClick(View view) {
//        		List<MessageObject> objects = new LinkedList<MessageObject>();
//        		objects.add(new MessageObject(1, 1, 1, "Lamp1", "0"));
//        		objects.add(new MessageObject(2, 1, 1, "Lamp2", "1"));
//        		objects.add(new MessageObject(3, 1, 1, "Lamp3", "1"));
//        		objects.add(new MessageObject(4, 1, 1, "Lamp4", "0"));
//        		binder.sendSetObjects(objects);
//        	}
//        });

        class MyOnClickListener implements OnClickListener {
        	private int visibleId;
        	MyOnClickListener(int visibleId) {
        		this.visibleId = visibleId;

        	}
        	public void onClick(View view) {
        		// Hide all tabs...
        		hideAllTabs();
				// ...but the current one.
        		LinearLayout ll = messageTabs.get(visibleId).layout;
        		ll.setVisibility(View.VISIBLE);
        		// Get relevant objects for this tab.
   				binder.sendGetAllObjects(visibleId);
        	}
        }
        Button buPanelLight = (Button)findViewById(R.id.smButtonPanelLight);
        Button buPanelAC = (Button)findViewById(R.id.smButtonPanelAC);
        Button buPanelHeating = (Button)findViewById(R.id.smButtonPanelHeating);
        Button buPanelSecurity = (Button)findViewById(R.id.smButtonPanelSecurity);
        Button buPanelMacros = (Button)findViewById(R.id.smButtonPanelMacros);

        messageTabs = new SparseArray<ServerMessageTab>(4);
        messageTabs.put(OBJECT_TYPE_LIGTH, new ServerMessageTab(buPanelLight,		(LinearLayout)ServerMessagesActivity.this.findViewById(R.id.smLight), R.drawable.sm_1_00, R.drawable.sm_1_99));
        messageTabs.put(OBJECT_TYPE_AC, new ServerMessageTab(buPanelAC,				(LinearLayout)ServerMessagesActivity.this.findViewById(R.id.smAC), R.drawable.sm_5_00, R.drawable.sm_5_99));
        messageTabs.put(OBJECT_TYPE_HEAT, new ServerMessageTab(buPanelHeating,		(LinearLayout)ServerMessagesActivity.this.findViewById(R.id.smHeating), R.drawable.sm_3_00, R.drawable.sm_3_99));
        messageTabs.put(OBJECT_TYPE_SECURITY, new ServerMessageTab(buPanelSecurity,	(LinearLayout)ServerMessagesActivity.this.findViewById(R.id.smSecurity), R.drawable.sm_7_00, R.drawable.sm_7_99));
        messageTabs.put(OBJECT_TYPE_MACROS, new ServerMessageTab(buPanelMacros,		(LinearLayout)ServerMessagesActivity.this.findViewById(R.id.smMacros), R.drawable.sm_10_00, R.drawable.sm_10_99));

        buPanelLight.setOnClickListener(new MyOnClickListener(OBJECT_TYPE_LIGTH));
        buPanelAC.setOnClickListener(new MyOnClickListener(OBJECT_TYPE_AC));
        buPanelHeating.setOnClickListener(new MyOnClickListener(OBJECT_TYPE_HEAT));
        buPanelSecurity.setOnClickListener(new MyOnClickListener(OBJECT_TYPE_SECURITY));
        buPanelMacros.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// Hide all tabs...
				hideAllTabs();
				// ...but the current one.
        		LinearLayout ll = messageTabs.get(OBJECT_TYPE_MACROS).layout;
        		ll.setVisibility(View.VISIBLE);
        		// Get relevant objects for this tab.
   				binder.sendGetAllMacros();
			}
		});

		// Register to receive messages from PositionerService.
		// We are registering an observer (mMessageReceiver) to receive Intents with actions named "serverMessageEvent".
		LocalBroadcastManager.getInstance(this).registerReceiver(toastMessageReceiver, new IntentFilter("toastEvent"));
		IntentFilter intentFilter = new IntentFilter();
		intentFilter.addAction("serverMessageEvent");
		intentFilter.addAction("MacrosEvent");
		LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, intentFilter);

		// Bind to LocalService
		Intent intent = new Intent(this, PositionerService.class);
		bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
		Log.d(getClass().getSimpleName(), "After onCreate");
	}

	@Override
	protected void onStart() {
		// The activity is about to become visible.
		super.onStart();
		Log.d(getClass().getSimpleName(), "After onStart");
	}

	@Override
	protected void onResume() {
		// The activity has become visible (it is now "resumed").
		super.onResume();
		Log.d(getClass().getSimpleName(), "After onResume");
	}

	@Override
	protected void onPause() {
		// Another activity is taking focus (this activity is about to be "paused").
		super.onPause();
		Log.d(getClass().getSimpleName(), "After onPause");
	}

	@Override
	protected void onStop() {
		// The activity is no longer visible (it is now "stopped")
		super.onStop();
		Log.d(getClass().getSimpleName(), "After onStop");
	}

	@Override
	protected void onDestroy() {
		// The activity is about to be destroyed.
		super.onDestroy();
		// Unregister since the activity is about to be closed.
		if(toastMessageReceiver != null) {
			LocalBroadcastManager.getInstance(this).unregisterReceiver(toastMessageReceiver);
		}
		if(mMessageReceiver != null) {
			LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
		}
		// Unbind from the service
		if(binder != null) {
			unbindService(mConnection);
		}
		Log.d(getClass().getSimpleName(), "After onDestroy");
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
	}
	protected void onRestoreInstanceState(Bundle savedInstanceState) {
		super.onRestoreInstanceState(savedInstanceState);
	}

	/** Defines callsbacks for service binding, passed to bindService() */
	private ServiceConnection mConnection = new ServiceConnection() {
		@Override
		public void onServiceConnected(ComponentName className, IBinder service) {
			// We've bound to LocalService, cast the IBinder and get LocalService instance
			binder = (PositionerService.LocalBinder) service;
		}

		@Override
		public void onServiceDisconnected(ComponentName arg0) {
			binder = null;
		}
	};
}